package com.fire.service.impl;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson2.JSON;
import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;
import com.fire.mapper.NoticeMapper;
import com.fire.mapper.SmartMapper;
import com.fire.model.entity.Monitor;
import com.fire.model.entity.Notice;
import com.fire.model.entity.Smart;
import com.fire.service.IAsyncService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.mail.SimpleMailMessage;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.stream.Collectors;

/**
 * ClassName: AsyncServiceImpl
 * Package: com.fire.service.impl
 * Description:
 *
 * @Author: @weixueshi
 * @Create: 2024/3/29 - 0:38
 * @Version: v1.0
 */

/**
 * 异步服务实现类
 */
@Slf4j
@Async("asyncExecutor")
@Service
@RequiredArgsConstructor
public class AsyncServiceImpl implements IAsyncService {

    private final NoticeMapper noticeMapper;
    private final SmartMapper smartMapper;

    /**
     * 邮件发送者
     */
    @Value("${spring.mail.username}")
    private String username;

    @Value("${amap.key}")
    private String key;

    private static String URL = "https://restapi.amap.com/v3/geocode/geo?address=";

    private static String PARAMETERS = "&output=JSON&key=";

    private static final String MACHINE_TITLE = "机器故障通知";
    private static final String MONITOR_TITLE = "监测警告通知";

    private static final String TEMPLATE = "尊敬的管理员：部分机器发生了故障，请尽快处理！编号：";
    private static final String MONITOR_TEMPLATE = "尊敬的管理员：监测数据有异常，请尽快处理！";

    /**
     * 注入QQ发送邮件的bean
     */
    @Autowired
    private JavaMailSender javaMailSender;

    /**
     * 机器故障发送文本邮件
     *
     * @param content
     */
    @Override
    public void sendMachineMail(String content) {
        try {
            log.info("邮箱准备发送：故障机器为：{}",content);
            SimpleMailMessage mailMessage= new SimpleMailMessage();
            //发送者
            mailMessage.setFrom(this.username);
            //接收者
            mailMessage.setTo(this.username);
            //邮件标题
            mailMessage.setSubject(MACHINE_TITLE);
            //邮件内容
            mailMessage.setText(TEMPLATE + content);
            Notice notice = new Notice();
            notice.setTitle(MACHINE_TITLE);
            notice.setContent(TEMPLATE + content);
            noticeMapper.insert(notice);
            //发送邮箱
            javaMailSender.send(mailMessage);
            log.info("邮箱发送成功：故障机器为：{}",content);
        } catch (Exception e) {
            log.info("邮箱发送失败：故障机器为：{}",content);
        }
    }

    /**
     * 监测数据警告发送文本邮件
     *
     * @param content
     */
    @Override
    public void sendMonitorMail(String content) {
        try {
            log.info("邮箱准备发送：监测数据警告为：{}",content);
            SimpleMailMessage mailMessage= new SimpleMailMessage();
            //发送者
            mailMessage.setFrom(this.username);
            //接收者
            mailMessage.setTo(this.username);
            //邮件标题
            mailMessage.setSubject(MONITOR_TITLE);
            //邮件内容
            mailMessage.setText(MONITOR_TEMPLATE + content);
            Notice notice = new Notice();
            notice.setTitle(MONITOR_TITLE);
            notice.setContent(MONITOR_TEMPLATE + content);
            noticeMapper.insert(notice);
            //发送邮箱
            javaMailSender.send(mailMessage);
            log.info("邮箱发送成功：监测数据警告为：{}",content);
        } catch (Exception e) {
            log.info("邮箱发送失败：监测数据警告为：{}",content);
        }
    }

    @Override
    public void saveSmartInfo(List<Monitor> warnMonitors) {
        List<String> locationNames = warnMonitors.stream().map(Monitor::getLocation).collect(Collectors.toList());
        //插入数据前需要去查询位置名称所处的经纬度数据一并写入f_smart表
        log.info("开始写入f_smart数据......");
        long begin = System.currentTimeMillis();
        locationNames.stream().forEach(item ->{
            String jsonStr = HttpUtil.get(URL + item + PARAMETERS + key);
            JSONObject jsonObject = JSON.parseObject(jsonStr);
            String status = jsonObject.getString("status");
            if("1".equalsIgnoreCase(status)){
                JSONArray jsonArray = jsonObject.getJSONArray("geocodes");
                JSONObject object = (JSONObject) jsonArray.get(0);
                String[] split = object.getString("location").split(",");
                Smart smart = new Smart();
                smart.setLongitude(split[0]);
                smart.setLatitude(split[1]);
                smart.setLocationName(item);
                smartMapper.insert(smart);
            }
        });
        long end = System.currentTimeMillis();
        log.info("写入f_smart数据耗时：{}s",(end-begin)/1000);
    }
}
